package org.adorsys.aderp.aderplogin.client.hessian;

import java.io.IOException;
import java.nio.charset.Charset;

import org.adorsys.aderp.aderplogin.client.common.Oauth2User;
import org.codehaus.jackson.JsonEncoding;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.MultiValueMap;

public class Oauth2UserHttpFormMessageConverter extends AbstractHttpMessageConverter<Oauth2User>{

	private final FormHttpMessageConverter delegateMessageConverter;

	public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
	
	public Oauth2UserHttpFormMessageConverter() {
		super(MediaType.APPLICATION_FORM_URLENCODED);
		this.delegateMessageConverter = new FormHttpMessageConverter();
	}

	@Override
	protected boolean supports(Class<?> clazz) {
		return Oauth2User.class.isAssignableFrom(clazz);
	}

	@Override
	protected boolean canRead(MediaType mediaType) {
		return super.canRead(mediaType);
	}

	@Override
	public boolean canRead(Class<?> clazz, MediaType mediaType) {
		return super.canRead(clazz, mediaType);
	}

	@Override
	protected Oauth2User readInternal(Class<? extends Oauth2User> clazz,
			HttpInputMessage inputMessage) throws IOException,
			HttpMessageNotReadableException {
		MultiValueMap<String, String> data = delegateMessageConverter.read(null, inputMessage);
		return Oauth2User.valueOf(data.toSingleValueMap());
	}

	@Override
	protected void writeInternal(Oauth2User t, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException {
		throw new UnsupportedOperationException(
				"This converter is only used for converting from externally aqcuired form data");
	}

	/**
	 * Determine the JSON encoding to use for the given content type.
	 * @param contentType the media type as requested by the caller
	 * @return the JSON encoding to use (never <code>null</code>)
	 */
	protected JsonEncoding getJsonEncoding(MediaType contentType) {
		if (contentType != null && contentType.getCharSet() != null) {
			Charset charset = contentType.getCharSet();
			for (JsonEncoding encoding : JsonEncoding.values()) {
				if (charset.name().equals(encoding.getJavaName())) {
					return encoding;
				}
			}
		}
		return JsonEncoding.UTF8;
	}
}
